home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr26 / netprog.zip / NETPROG.TAR / tftp / error.c < prev    next >
C/C++ Source or Header  |  1989-12-17  |  7KB  |  379 lines

  1. /*
  2.  * Error handling routines.
  3.  *
  4.  * The functions in this file are independent of any application
  5.  * variables, and may be used with any C program.
  6.  * Either of the names CLIENT or SERVER may be defined when compiling
  7.  * this function.  If neither are defined, we assume CLIENT.
  8.  */
  9.  
  10. #include    <stdio.h>
  11. #include    <varargs.h>
  12.  
  13. #include    "systype.h"
  14.  
  15. #ifdef    CLIENT
  16. #ifdef    SERVER
  17. cant define both CLIENT and SERVER
  18. #endif
  19. #endif
  20.  
  21. #ifndef    CLIENT
  22. #ifndef    SERVER
  23. #define    CLIENT    1        /* default to client */
  24. #endif
  25. #endif
  26.  
  27. #ifndef    NULL
  28. #define    NULL    ((void *) 0)
  29. #endif
  30.  
  31. char    *pname = NULL;
  32.  
  33. #ifdef    CLIENT            /* these all output to stderr */
  34.  
  35. /*
  36.  * Fatal error.  Print a message and terminate.
  37.  * Don't dump core and don't print the system's errno value.
  38.  *
  39.  *    err_quit(str, arg1, arg2, ...)
  40.  *
  41.  * The string "str" must specify the conversion specification for any args.
  42.  */
  43.  
  44. /*VARARGS1*/
  45. err_quit(va_alist)
  46. va_dcl
  47. {
  48.     va_list        args;
  49.     char        *fmt;
  50.  
  51.     va_start(args);
  52.     if (pname != NULL)
  53.         fprintf(stderr, "%s: ", pname);
  54.     fmt = va_arg(args, char *);
  55.     vfprintf(stderr, fmt, args);
  56.     fputc('\n', stderr);
  57.     va_end(args);
  58.  
  59.     exit(1);
  60. }
  61.  
  62. /*
  63.  * Fatal error related to a system call.  Print a message and terminate.
  64.  * Don't dump core, but do print the system's errno value and its
  65.  * associated message.
  66.  *
  67.  *    err_sys(str, arg1, arg2, ...)
  68.  *
  69.  * The string "str" must specify the conversion specification for any args.
  70.  */
  71.  
  72. /*VARARGS1*/
  73. err_sys(va_alist)
  74. va_dcl
  75. {
  76.     va_list        args;
  77.     char        *fmt;
  78.  
  79.     va_start(args);
  80.     if (pname != NULL)
  81.         fprintf(stderr, "%s: ", pname);
  82.     fmt = va_arg(args, char *);
  83.     vfprintf(stderr, fmt, args);
  84.     va_end(args);
  85.  
  86.     my_perror();
  87.  
  88.     exit(1);
  89. }
  90.  
  91. /*
  92.  * Recoverable error.  Print a message, and return to caller.
  93.  *
  94.  *    err_ret(str, arg1, arg2, ...)
  95.  *
  96.  * The string "str" must specify the conversion specification for any args.
  97.  */
  98.  
  99. /*VARARGS1*/
  100. err_ret(va_alist)
  101. va_dcl
  102. {
  103.     va_list        args;
  104.     char        *fmt;
  105.  
  106.     va_start(args);
  107.     if (pname != NULL)
  108.         fprintf(stderr, "%s: ", pname);
  109.     fmt = va_arg(args, char *);
  110.     vfprintf(stderr, fmt, args);
  111.     va_end(args);
  112.  
  113.     my_perror();
  114.  
  115.     fflush(stdout);
  116.     fflush(stderr);
  117.  
  118.     return;
  119. }
  120.  
  121. /*
  122.  * Fatal error.  Print a message, dump core (for debugging) and terminate.
  123.  *
  124.  *    err_dump(str, arg1, arg2, ...)
  125.  *
  126.  * The string "str" must specify the conversion specification for any args.
  127.  */
  128.  
  129. /*VARARGS1*/
  130. err_dump(va_alist)
  131. va_dcl
  132. {
  133.     va_list        args;
  134.     char        *fmt;
  135.  
  136.     va_start(args);
  137.     if (pname != NULL)
  138.         fprintf(stderr, "%s: ", pname);
  139.     fmt = va_arg(args, char *);
  140.     vfprintf(stderr, fmt, args);
  141.     va_end(args);
  142.  
  143.     my_perror();
  144.  
  145.     fflush(stdout);        /* abort doesn't flush stdio buffers */
  146.     fflush(stderr);
  147.  
  148.     abort();        /* dump core and terminate */
  149.     exit(1);        /* shouldn't get here */
  150. }
  151.  
  152. /*
  153.  * Print the UNIX errno value.
  154.  */
  155.  
  156. my_perror()
  157. {
  158.     char    *sys_err_str();
  159.  
  160.     fprintf(stderr, " %s\n", sys_err_str());
  161. }
  162.  
  163. #endif    /* CLIENT */
  164.  
  165. #ifdef    SERVER
  166.  
  167. #ifdef    BSD
  168. /*
  169.  * Under BSD, these server routines use the syslog(3) facility.
  170.  * They don't append a newline, for example.
  171.  */
  172.  
  173. #include    <syslog.h>
  174.  
  175. #else    /* not BSD */
  176. /*
  177.  * There really ought to be a better way to handle server logging
  178.  * under System V.
  179.  */
  180.  
  181. #define    syslog(a,b)    fprintf(stderr, "%s\n", (b))
  182. #define    openlog(a,b,c)    fprintf(stderr, "%s\n", (a))
  183.  
  184. #endif    /* BSD */
  185.  
  186. char    emesgstr[255] = {0};    /* used by all server routines */
  187.  
  188. /*
  189.  * Identify ourself, for syslog() messages.
  190.  *
  191.  * LOG_PID is an option that says prepend each message with our pid.
  192.  * LOG_CONS is an option that says write to console if unable to send
  193.  * the message to syslogd.
  194.  * LOG_DAEMON is our facility.
  195.  */
  196.  
  197. err_init(ident)
  198. char    *ident;
  199. {
  200.     openlog(ident, (LOG_PID | LOG_CONS), LOG_DAEMON);
  201. }
  202.  
  203. /*
  204.  * Fatal error.  Print a message and terminate.
  205.  * Don't print the system's errno value.
  206.  *
  207.  *    err_quit(str, arg1, arg2, ...)
  208.  *
  209.  * The string "str" must specify the conversion specification for any args.
  210.  */
  211.  
  212. /*VARARGS1*/
  213. err_quit(va_alist)
  214. va_dcl
  215. {
  216.     va_list        args;
  217.     char        *fmt;
  218.  
  219.     va_start(args);
  220.     fmt = va_arg(args, char *);
  221.     vsprintf(emesgstr, fmt, args);
  222.     va_end(args);
  223.  
  224.     syslog(LOG_ERR, emesgstr);
  225.  
  226.     exit(1);
  227. }
  228.  
  229. /*
  230.  * Fatal error related to a system call.  Print a message and terminate.
  231.  * Don't dump core, but do print the system's errno value and its
  232.  * associated message.
  233.  *
  234.  *    err_sys(str, arg1, arg2, ...)
  235.  *
  236.  * The string "str" must specify the conversion specification for any args.
  237.  */
  238.  
  239. /*VARARGS1*/
  240. err_sys(va_alist)
  241. va_dcl
  242. {
  243.     va_list        args;
  244.     char        *fmt;
  245.  
  246.     va_start(args);
  247.     fmt = va_arg(args, char *);
  248.     vsprintf(emesgstr, fmt, args);
  249.     va_end(args);
  250.  
  251.     my_perror();
  252.     syslog(LOG_ERR, emesgstr);
  253.  
  254.     exit(1);
  255. }
  256.  
  257. /*
  258.  * Recoverable error.  Print a message, and return to caller.
  259.  *
  260.  *    err_ret(str, arg1, arg2, ...)
  261.  *
  262.  * The string "str" must specify the conversion specification for any args.
  263.  */
  264.  
  265. /*VARARGS1*/
  266. err_ret(va_alist)
  267. va_dcl
  268. {
  269.     va_list        args;
  270.     char        *fmt;
  271.  
  272.     va_start(args);
  273.     fmt = va_arg(args, char *);
  274.     vsprintf(emesgstr, fmt, args);
  275.     va_end(args);
  276.  
  277.     my_perror();
  278.     syslog(LOG_ERR, emesgstr);
  279.  
  280.     return;
  281. }
  282.  
  283. /*
  284.  * Fatal error.  Print a message, dump core (for debugging) and terminate.
  285.  *
  286.  *    err_dump(str, arg1, arg2, ...)
  287.  *
  288.  * The string "str" must specify the conversion specification for any args.
  289.  */
  290.  
  291. /*VARARGS1*/
  292. err_dump(va_alist)
  293. va_dcl
  294. {
  295.     va_list        args;
  296.     char        *fmt;
  297.  
  298.     va_start(args);
  299.     fmt = va_arg(args, char *);
  300.     vsprintf(emesgstr, fmt, args);
  301.     va_end(args);
  302.  
  303.     my_perror();
  304.     syslog(LOG_ERR, emesgstr);
  305.  
  306.     abort();        /* dump core and terminate */
  307.     exit(1);        /* shouldn't get here */
  308. }
  309.  
  310. /*
  311.  * Print the UNIX errno value.
  312.  * We just append it to the end of the emesgstr[] array.
  313.  */
  314.  
  315. my_perror()
  316. {
  317.     register int    len;
  318.     char        *sys_err_str();
  319.  
  320.     len = strlen(emesgstr);
  321.     sprintf(emesgstr + len, " %s", sys_err_str());
  322. }
  323.  
  324. #endif    /* SERVER */
  325.  
  326.             /* remainder is for both CLIENT and SERVER */
  327. extern int    errno;        /* Unix error number */
  328. extern int    sys_nerr;    /* # of error message strings in sys table */
  329. extern char    *sys_errlist[];    /* the system error message table */
  330.  
  331. #ifdef    SYS5
  332. int    t_errno;    /* in case caller is using TLI, these are "tentative
  333.                definitions"; else they're "definitions" */
  334. int    t_nerr;
  335. char    *t_errlist[1];
  336. #endif
  337.  
  338.  
  339. /*
  340.  * Return a string containing some additional operating-system
  341.  * dependent information.
  342.  * Note that different versions of UNIX assign different meanings
  343.  * to the same value of "errno" (compare errno's starting with 35
  344.  * between System V and BSD, for example).  This means that if an error
  345.  * condition is being sent to another UNIX system, we must interpret
  346.  * the errno value on the system that generated the error, and not
  347.  * just send the decimal value of errno to the other system.
  348.  */
  349.  
  350. char *
  351. sys_err_str()
  352. {
  353.     static char    msgstr[200];
  354.  
  355.     if (errno != 0) {
  356.         if (errno > 0 && errno < sys_nerr)
  357.             sprintf(msgstr, "(%s)", sys_errlist[errno]);
  358.         else
  359.             sprintf(msgstr, "(errno = %d)", errno);
  360.     } else {
  361.         msgstr[0] = '\0';
  362.     }
  363.  
  364. #ifdef    SYS5
  365.     if (t_errno != 0) {
  366.         char    tmsgstr[100];
  367.  
  368.         if (t_errno > 0 && t_errno < sys_nerr)
  369.             sprintf(tmsgstr, " (%s)", t_errlist[t_errno]);
  370.         else
  371.             sprintf(tmsgstr, ", (t_errno = %d)", t_errno);
  372.  
  373.         strcat(msgstr, tmsgstr);    /* catenate strings */
  374.     }
  375. #endif
  376.  
  377.     return(msgstr);
  378. }
  379.